<!doctype html>
<html lang="en" data-color-mode="dark">
<head>
<meta charset="utf-8">
<title>make 备忘清单
 &#x26;  make cheatsheet &#x26;  Quick Reference</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta description="包含 最重要概念、函数、方法等的 make 备忘单。 初学者的完整快速参考。

Makefile 入门，为开发人员分享快速参考备忘单。">
<meta keywords="make,reference,Quick,Reference,cheatsheet,cheat,sheet">
<link rel="icon" href="data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20height%3D%221em%22%20width%3D%221em%22%3E%20%3Cpath%20d%3D%22m21.66%2010.44-.98%204.18c-.84%203.61-2.5%205.07-5.62%204.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2%201.17-2.42%203.16-3.07%206.5-2.28l1.67.39c4.19.98%205.47%203.05%204.49%207.23Z%22%20fill%3D%22%23c9d1d9%22%2F%3E%20%3Cpath%20d%3D%22M15.06%2019.39c-.62.42-1.4.77-2.35%201.08l-1.58.52c-3.97%201.28-6.06.21-7.35-3.76L2.5%2013.28c-1.28-3.97-.22-6.07%203.75-7.35l1.58-.52c.41-.13.8-.24%201.17-.31-.3.61-.54%201.35-.74%202.2l-.98%204.19c-.98%204.18.31%206.24%204.48%207.23l1.68.4c.58.14%201.12.23%201.62.27Zm2.43-8.88c-.06%200-.12-.01-.19-.02l-4.85-1.23a.75.75%200%200%201%20.37-1.45l4.85%201.23a.748.748%200%200%201-.18%201.47Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3Cpath%20d%3D%22M14.56%2013.89c-.06%200-.12-.01-.19-.02l-2.91-.74a.75.75%200%200%201%20.37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z%22%20fill%3D%22%23228e6c%22%20%2F%3E%20%3C%2Fsvg%3E" type="image/svg+xml">
<link rel="stylesheet" href="../style/style.css">
<link rel="stylesheet" href="../style/katex.css">
</head>
<body><nav class="header-nav"><div class="max-container"><a href="../index.html" class="logo"><svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" height="1em" width="1em">
  <path d="m21.66 10.44-.98 4.18c-.84 3.61-2.5 5.07-5.62 4.77-.5-.04-1.04-.13-1.62-.27l-1.68-.4c-4.17-.99-5.46-3.05-4.48-7.23l.98-4.19c.2-.85.44-1.59.74-2.2 1.17-2.42 3.16-3.07 6.5-2.28l1.67.39c4.19.98 5.47 3.05 4.49 7.23Z" fill="#c9d1d9"></path>
  <path d="M15.06 19.39c-.62.42-1.4.77-2.35 1.08l-1.58.52c-3.97 1.28-6.06.21-7.35-3.76L2.5 13.28c-1.28-3.97-.22-6.07 3.75-7.35l1.58-.52c.41-.13.8-.24 1.17-.31-.3.61-.54 1.35-.74 2.2l-.98 4.19c-.98 4.18.31 6.24 4.48 7.23l1.68.4c.58.14 1.12.23 1.62.27Zm2.43-8.88c-.06 0-.12-.01-.19-.02l-4.85-1.23a.75.75 0 0 1 .37-1.45l4.85 1.23a.748.748 0 0 1-.18 1.47Z" fill="#228e6c"></path>
  <path d="M14.56 13.89c-.06 0-.12-.01-.19-.02l-2.91-.74a.75.75 0 0 1 .37-1.45l2.91.74c.4.1.64.51.54.91-.08.34-.38.56-.72.56Z" fill="#228e6c"></path>
</svg>
<span class="title">Quick Reference</span></a><div class="menu"><a href="javascript:void(0);" class="searchbtn" id="searchbtn"><svg xmlns="http://www.w3.org/2000/svg" height="1em" width="1em" viewBox="0 0 18 18">
  <path fill="currentColor" d="M17.71,16.29 L14.31,12.9 C15.4069846,11.5024547 16.0022094,9.77665502 16,8 C16,3.581722 12.418278,0 8,0 C3.581722,0 0,3.581722 0,8 C0,12.418278 3.581722,16 8,16 C9.77665502,16.0022094 11.5024547,15.4069846 12.9,14.31 L16.29,17.71 C16.4777666,17.8993127 16.7333625,18.0057983 17,18.0057983 C17.2666375,18.0057983 17.5222334,17.8993127 17.71,17.71 C17.8993127,17.5222334 18.0057983,17.2666375 18.0057983,17 C18.0057983,16.7333625 17.8993127,16.4777666 17.71,16.29 Z M2,8 C2,4.6862915 4.6862915,2 8,2 C11.3137085,2 14,4.6862915 14,8 C14,11.3137085 11.3137085,14 8,14 C4.6862915,14 2,11.3137085 2,8 Z"></path>
</svg><span>搜索</span><span>⌘K</span></a><a href="https://github.com/jaywcjlove/reference/blob/main/docs/make.md" class="" target="__blank"><svg viewBox="0 0 36 36" fill="currentColor" height="1em" width="1em"><path d="m33 6.4-3.7-3.7a1.71 1.71 0 0 0-2.36 0L23.65 6H6a2 2 0 0 0-2 2v22a2 2 0 0 0 2 2h22a2 2 0 0 0 2-2V11.76l3-3a1.67 1.67 0 0 0 0-2.36ZM18.83 20.13l-4.19.93 1-4.15 9.55-9.57 3.23 3.23ZM29.5 9.43 26.27 6.2l1.85-1.85 3.23 3.23Z"></path><path fill="none" d="M0 0h36v36H0z"></path></svg><span>编辑</span></a><button id="darkMode" type="button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="light" height="1em" width="1em">
  <path d="M6.995 12c0 2.761 2.246 5.007 5.007 5.007s5.007-2.246 5.007-5.007-2.246-5.007-5.007-5.007S6.995 9.239 6.995 12zM11 19h2v3h-2zm0-17h2v3h-2zm-9 9h3v2H2zm17 0h3v2h-3zM5.637 19.778l-1.414-1.414 2.121-2.121 1.414 1.414zM16.242 6.344l2.122-2.122 1.414 1.414-2.122 2.122zM6.344 7.759 4.223 5.637l1.415-1.414 2.12 2.122zm13.434 10.605-1.414 1.414-2.122-2.122 1.414-1.414z"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" class="dark" height="1em" width="1em">
  <path d="M12 11.807A9.002 9.002 0 0 1 10.049 2a9.942 9.942 0 0 0-5.12 2.735c-3.905 3.905-3.905 10.237 0 14.142 3.906 3.906 10.237 3.905 14.143 0a9.946 9.946 0 0 0 2.735-5.119A9.003 9.003 0 0 1 12 11.807z"></path>
</svg>
</button><script src="../js/dark.js?v=1.5.2"></script><a href="https://github.com/jaywcjlove/reference" class="" target="__blank"><svg viewBox="0 0 16 16" fill="currentColor" height="1em" width="1em"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg></a></div></div></nav><div class="wrap h1body-exist max-container"><header class="wrap-header h1wrap"><h1 id="make-备忘清单"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" fill="currentColor" height="1em" width="1em">
  <path d="M107.946667 838.4l57.173333 23.893333v-385.28l-103.68 250.026667c-17.493333 43.52 3.413333 93.44 46.506667 111.36z m832-157.866667L728.32 169.813333a85.888 85.888 0 0 0-77.226667-52.48c-11.093333 0-22.613333 1.706667-33.706666 6.4L302.933333 253.866667a85.290667 85.290667 0 0 0-46.08 110.933333l211.626667 510.72a85.248 85.248 0 0 0 110.933333 46.08l314.026667-130.133333a85.077333 85.077333 0 0 0 46.506667-110.933334zM336.213333 373.333333c-23.466667 0-42.666667-19.2-42.666666-42.666666s19.2-42.666667 42.666666-42.666667 42.666667 19.2 42.666667 42.666667-19.2 42.666667-42.666667 42.666666z m-85.333333 469.333334c0 46.933333 38.4 85.333333 85.333333 85.333333h61.866667l-147.2-355.84v270.506667z"></path>
</svg><a aria-hidden="true" tabindex="-1" href="#make-备忘清单"><span class="icon icon-link"></span></a>make 备忘清单</h1><div class="wrap-body">
<p>包含 最重要概念、函数、方法等的 make 备忘单。 初学者的完整快速参考。</p>
</div></header><div class="menu-tocs"><div class="menu-btn"><svg aria-hidden="true" fill="currentColor" height="1em" width="1em" viewBox="0 0 16 16" version="1.1" data-view-component="true">
  <path fill-rule="evenodd" d="M2 4a1 1 0 100-2 1 1 0 000 2zm3.75-1.5a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5zm0 5a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5zm0 5a.75.75 0 000 1.5h8.5a.75.75 0 000-1.5h-8.5zM3 8a1 1 0 11-2 0 1 1 0 012 0zm-1 6a1 1 0 100-2 1 1 0 000 2z"></path>
</svg></div><div class="menu-modal"><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#makefile-入门">Makefile 入门</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#示例">示例</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#工作流程">工作流程</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#文件命令">文件命令</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#自定义文件路径">自定义文件路径</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#隐式生成">隐式生成</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#规则">规则</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#清空目标文件">清空目标文件</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#注释">注释</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#换行-">换行 \</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#引用其它的-makefile">引用其它的 Makefile</a><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#变量">变量</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#赋值符">赋值符</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#在执行时扩展允许递归扩展">在执行时扩展，允许递归扩展</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#在声明时扩展">在声明时扩展</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#只有在该变量为空时才设置值">只有在该变量为空时才设置值</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#将值追加到变量的尾端">将值追加到变量的尾端</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#override">override</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#变量-1">变量</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#避免递归变量">避免递归变量</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#shell-变量">Shell 变量</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#定义多行变量">定义多行变量</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#自动变量">自动变量</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#">$@</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-1">$&#x3C;</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-2">$^</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-3">$+</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-4">$?</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-5">$*</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-6">$%</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#内置命名变量的参数">内置命名变量的参数</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#内置已命名的变量">内置已命名的变量</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#内置的变量">内置的变量</a><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#书写规则">书写规则</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#文件搜寻vpath">文件搜寻（vpath）</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-7">%</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#通配符">通配符</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-8">*</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-9">~</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#-10">?</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#静态模式">静态模式</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#伪目标">伪目标</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#约定俗成的规则">约定俗成的规则</a><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#命令">命令</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#回声">回声（@）</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#显示命令禁止命令">显示命令、禁止命令</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#显示命令">显示命令</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#禁止命令">禁止命令</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#执行命令">执行命令</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#make-参数">make 参数</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#-debugoptions">-debug[=&#x3C;options>]</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#make-的退出码">make 的退出码</a><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#判断和循环">判断和循环</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#单分支条件判断">单分支条件判断</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#多分支条件判断">多分支条件判断</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#ifneq-语法">ifneq 语法</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#ifeq-语法">ifeq 语法</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#ifdef">ifdef</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#for-循环">for 循环</a><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#函数">函数</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---替换函数subst">字符串处理函数 - 替换函数(subst)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---模式字符串替换函数patsubst">字符串处理函数 - 模式字符串替换函数(patsubst)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---去空格函数strip">字符串处理函数 - 去空格函数(strip)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---查找字符串函数findstring">字符串处理函数 - 查找字符串函数(findstring)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---过滤函数filter">字符串处理函数 - 过滤函数(filter)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---反过滤函数filter-out">字符串处理函数 - 反过滤函数(filter-out)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---排序函数sort">字符串处理函数 - 排序函数(sort)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---取单词函数word">字符串处理函数 - 取单词函数（word)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---取单词串函数wordlist">字符串处理函数 - 取单词串函数(wordlist)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---单词个数统计函数words">字符串处理函数 - 单词个数统计函数(words)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#字符串处理函数---首单词函数firstword">字符串处理函数 - 首单词函数(firstword)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#文件名操作函数">文件名操作函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#取目录函数dir">取目录函数(dir)</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#取文件函数notdir">取文件函数(notdir)</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#取后缀函数suffix">取后缀函数（suffix)</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#取前缀函数basename">取前缀函数(basename)</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#加后缀函数addsuffix">加后缀函数(addsuffix)</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#加前缀函数addprefix">加前缀函数(addprefix)</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#连接函数join">连接函数(join)</a><a aria-hidden="true" class="leve3 tocs-link" data-num="3" href="#其它函数">其它函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#foreach-函数">foreach 函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#if-函数">if 函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#call-函数">call 函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#shell-函数">shell 函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#控制-make-的函数">控制 make 的函数</a><a aria-hidden="true" class="leve4 tocs-link" data-num="4" href="#origin-函数">origin 函数</a><a aria-hidden="true" class="leve2 tocs-link" data-num="2" href="#另见">另见</a></div></div><div class="h1wrap-body"><div class="wrap h2body-exist"><div class="wrap-header h2wrap"><h2 id="makefile-入门"><a aria-hidden="true" tabindex="-1" href="#makefile-入门"><span class="icon icon-link"></span></a>Makefile 入门</h2><div class="wrap-body">
<!-- markdownlint-disable MD010 -->
</div></div><div class="h2wrap-body"><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="示例"><a aria-hidden="true" tabindex="-1" href="#示例"><span class="icon icon-link"></span></a>示例</h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">a.txt</span><span class="token punctuation">:</span> b.txt c.txt
</span><span class="code-line">	cat b.txt c.txt > a.txt
</span></code></pre>
<h4 id="工作流程"><a aria-hidden="true" tabindex="-1" href="#工作流程"><span class="icon icon-link"></span></a>工作流程</h4>
<ul class="style-timeline">
<li>读入所有的 <code>Makefile</code>。</li>
<li>读入被 <code>include</code> 的其它 <code>Makefile</code>。</li>
<li>初始化文件中的变量。</li>
<li>推导隐晦规则，并分析所有规则。</li>
<li>为所有的目标文件创建依赖关系链。</li>
<li>根据依赖关系，决定哪些目标要重新生成。</li>
<li>执行生成命令。</li>
</ul>
<!--rehype:className=style-timeline-->
</div></div></div><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="文件命令"><a aria-hidden="true" tabindex="-1" href="#文件命令"><span class="icon icon-link"></span></a>文件命令</h3><div class="wrap-body">
<p>make命令会以 <code>GNUmakefile</code>（不推荐使用）、<code>makefile</code>、<code>Makefile</code>（推荐使用）的顺序查找当前目录下的文件。</p>
<h4 id="自定义文件路径"><a aria-hidden="true" tabindex="-1" href="#自定义文件路径"><span class="icon icon-link"></span></a>自定义文件路径</h4>
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> target <span class="token parameter variable">-f</span> FILE
</span></code></pre>
<p>我们可以使用 <code>-f FILE</code> 来指定makefile文件的路径</p>
<h4 id="隐式生成"><a aria-hidden="true" tabindex="-1" href="#隐式生成"><span class="icon icon-link"></span></a>隐式生成</h4>
<p>如果文件夹中没有 makefile 文件，只有 main.c 源文件，那么我们可以使用 <code>make main.o</code> 隐式生成链接文件</p>
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> main.o
</span><span class="code-line"><span class="token comment"># 实际执行： cc    -c -o main.o main.c</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="规则"><a aria-hidden="true" tabindex="-1" href="#规则"><span class="icon icon-link"></span></a>规则</h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">TARGET</span><span class="token punctuation">:</span> PREREQUISITES
</span><span class="code-line">  COMMAMD
</span><span class="code-line">...
</span></code></pre>
<ul class="style-round">
<li><code>target</code>: 规则的目标。目标可以是规则的动作（如 <code>clean</code> 等），也可以是目标文件或者最后的可执行文件。</li>
<li><code>prerequisites</code>: 规则的依赖。生成规则目标文件所需要的文件名列表（通常一个目标依赖于一个或者多个文件）。</li>
<li><code>command</code>: 规则的命令行。规则要执行的动作（任意的 shell 命令或者在 shell 下执行的程序）。<span style="color:red">命令需要以 tab 键开头</span></li>
</ul>
<!--rehype:className=style-round-->
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> <span class="token punctuation">[</span>TARGET <span class="token punctuation">..</span>.<span class="token punctuation">]</span>
</span></code></pre>
<hr>
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span>        <span class="token comment"># 没有参数首先运行 TARGET</span>
</span><span class="code-line">$ <span class="token function">make</span> <span class="token builtin class-name">help</span>   <span class="token comment"># 显示可用目标</span>
</span><span class="code-line">$ <span class="token function">make</span> dist   <span class="token comment"># 从当前目录制作一个发布存档</span>
</span><span class="code-line">$ <span class="token function">make</span> check  <span class="token comment"># 无需安装的单元测试</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="清空目标文件"><a aria-hidden="true" tabindex="-1" href="#清空目标文件"><span class="icon icon-link"></span></a>清空目标文件</h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token builtin-target builtin">.PHONY</span><span class="token punctuation">:</span> clean
</span><span class="code-line"><span class="token target symbol">clean</span><span class="token punctuation">:</span>
</span><span class="code-line">  rm *.o temp
</span></code></pre>
<p><code>.PHONY</code> 内置命令将排除 clean 文件，不会因为当前目录中因为有 clean 文件而不会不执行 clean 伪目标</p>
<p class="auto-wrap"><span style="color:red">clean 从来都是放在文件的最后</span></p>
<!--rehype:className=auto-wrap-->
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="注释"><a aria-hidden="true" tabindex="-1" href="#注释"><span class="icon icon-link"></span></a>注释</h3><div class="wrap-body">
<p>makefile 文件的注释与 bash 脚本一致</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># 这是一个注释</span>
</span><span class="code-line"><span class="token target symbol">main.o</span> <span class="token punctuation">:</span> main.c
</span><span class="code-line">	cc -c main.c
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="换行-"><a aria-hidden="true" tabindex="-1" href="#换行-"><span class="icon icon-link"></span></a>换行 <code>\</code></h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># 这是一个注释</span>
</span><span class="code-line"><span class="token target symbol">main.o</span> <span class="token punctuation">:</span> main.c
</span><span class="code-line">	cc -c \
</span><span class="code-line">	main.c
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="引用其它的-makefile"><a aria-hidden="true" tabindex="-1" href="#引用其它的-makefile"><span class="icon icon-link"></span></a>引用其它的 Makefile</h3><div class="wrap-body">
<p><code>include</code> 关键字可以把别的 Makefile 包含进来。这样使用 make 运行的时候就会</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># makefile</span>
</span><span class="code-line"><span class="token keyword">include</span> foo.make
</span></code></pre>
<p>如果你想让 make 不理那些无法读取的文件，并且继续执行。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token keyword">-include</span> &#x3C;filename>
</span></code></pre>
</div></div></div></div></div><div class="wrap h2body-exist"><div class="wrap-header h2wrap"><h2 id="变量"><a aria-hidden="true" tabindex="-1" href="#变量"><span class="icon icon-link"></span></a>变量</h2><div class="wrap-body">
</div></div><div class="h2wrap-body"><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="赋值符"><a aria-hidden="true" tabindex="-1" href="#赋值符"><span class="icon icon-link"></span></a>赋值符</h3><div class="wrap-body">
<h4 id="在执行时扩展允许递归扩展"><a aria-hidden="true" tabindex="-1" href="#在执行时扩展允许递归扩展"><span class="icon icon-link"></span></a>在执行时扩展，允许递归扩展</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">VARIABLE <span class="token operator">=</span> value
</span></code></pre>
<h4 id="在声明时扩展"><a aria-hidden="true" tabindex="-1" href="#在声明时扩展"><span class="icon icon-link"></span></a>在声明时扩展</h4>
<p>可以防止递归，并且只能引用之前声明过的变量</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">VARIABLE <span class="token operator">:=</span> value
</span></code></pre>
<h4 id="只有在该变量为空时才设置值"><a aria-hidden="true" tabindex="-1" href="#只有在该变量为空时才设置值"><span class="icon icon-link"></span></a>只有在该变量为空时才设置值</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">VARIABLE <span class="token operator">?=</span> value
</span></code></pre>
<h4 id="将值追加到变量的尾端"><a aria-hidden="true" tabindex="-1" href="#将值追加到变量的尾端"><span class="icon icon-link"></span></a>将值追加到变量的尾端</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">VARIABLE <span class="token operator">+=</span> value
</span></code></pre>
<h4 id="override"><a aria-hidden="true" tabindex="-1" href="#override"><span class="icon icon-link"></span></a>override</h4>
<p>如果变量前不指定 <code>override</code>，那么命令行中指定的变量可以对 Makefile 中的变量重新定义。</p>
<pre class="auto-wrap"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># 不会重新定义</span>
</span><span class="code-line"><span class="token keyword">override</span> VARIABLE <span class="token operator">=</span> value
</span><span class="code-line"><span class="token keyword">override</span> VARIABLE <span class="token operator">:=</span> value
</span><span class="code-line"><span class="token keyword">override</span> VARIABLE <span class="token operator">?=</span> value
</span><span class="code-line"><span class="token keyword">override</span> VARIABLE <span class="token operator">+=</span> value
</span><span class="code-line"><span class="token keyword">override</span> <span class="token keyword">define</span>
</span><span class="code-line">  <span class="token comment">#...</span>
</span><span class="code-line"><span class="token keyword">endef</span>
</span></code></pre>
<!--rehype:className=auto-wrap-->
</div></div></div><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="变量-1"><a aria-hidden="true" tabindex="-1" href="#变量-1"><span class="icon icon-link"></span></a>变量</h3><div class="wrap-body">
<p>需要使用 <code>$()</code> 或者 <code>${}</code> 对变量进行引用</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">file <span class="token operator">=</span> main.c
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	clang -o hello <span class="token variable">$</span><span class="token punctuation">{</span>file<span class="token punctuation">}</span>
</span></code></pre>
<h4 id="避免递归变量"><a aria-hidden="true" tabindex="-1" href="#避免递归变量"><span class="icon icon-link"></span></a>避免递归变量</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># 这样会使变量陷入无穷递归</span>
</span><span class="code-line">A <span class="token operator">=</span> <span class="token variable">$</span><span class="token punctuation">(</span>B<span class="token punctuation">)</span>
</span><span class="code-line">B <span class="token operator">=</span> <span class="token variable">$</span><span class="token punctuation">(</span>A<span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">x <span class="token operator">:=</span> foo
</span><span class="code-line">y <span class="token operator">:=</span> <span class="token variable">$</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> bar
</span><span class="code-line">x <span class="token operator">:=</span> later
</span><span class="code-line">
</span><span class="code-line"><span class="token comment"># 等价于</span>
</span><span class="code-line"><span class="token comment"># x = later</span>
</span><span class="code-line"><span class="token comment"># y = foo bar</span>
</span></code></pre>
<h4 id="shell-变量"><a aria-hidden="true" tabindex="-1" href="#shell-变量"><span class="icon icon-link"></span></a>Shell 变量</h4>
<p>如果要使用 Shell 变量，需要在之前加上 <code>$</code></p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	echo <span class="token variable">$$HOME</span>
</span></code></pre>
<h4 id="定义多行变量"><a aria-hidden="true" tabindex="-1" href="#定义多行变量"><span class="icon icon-link"></span></a>定义多行变量</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token keyword">define</span> foo
</span><span class="code-line">echo foo
</span><span class="code-line">echo bar
</span><span class="code-line"><span class="token keyword">endef</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">{</span>foo<span class="token punctuation">}</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-exist row-span-2"><div class="wrap-header h3wrap"><h3 id="自动变量"><a aria-hidden="true" tabindex="-1" href="#自动变量"><span class="icon icon-link"></span></a>自动变量</h3><div class="wrap-body">
<!--rehype:wrap-class=row-span-2-->
<h4 id=""><a aria-hidden="true" tabindex="-1" href="#"><span class="icon icon-link"></span></a><code>$@</code></h4>
<p><code>$@</code>:指代当前目标，即 Make 命令当前构建的那个目标</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">foo</span><span class="token punctuation">:</span>
</span><span class="code-line">	touch <span class="token variable">$@</span>
</span></code></pre>
<hr>
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> foo
</span><span class="code-line"><span class="token comment"># $@ 就是指的这里的 foo</span>
</span></code></pre>
<h4 id="-1"><a aria-hidden="true" tabindex="-1" href="#-1"><span class="icon icon-link"></span></a><code>$&#x3C;</code></h4>
<p><code>$&#x3C;</code> 指代第一个前置条件。比如，规则为 t: p1 p2，那么 <code>$&#x3C;</code> 就指代 p1</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">a.md</span><span class="token punctuation">:</span> b.md c.md
</span><span class="code-line">  cp <span class="token variable">$&#x3C;</span> <span class="token variable">$@</span>
</span></code></pre>
<hr>
<p>使用 <code>make a.md</code>,相当于以下写法</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">a.md</span><span class="token punctuation">:</span> b.md c.md
</span><span class="code-line">    cp b.md a.md 
</span></code></pre>
<h4 id="-2"><a aria-hidden="true" tabindex="-1" href="#-2"><span class="icon icon-link"></span></a><code>$^</code></h4>
<p><code>$^</code> 指代所有的前置条件,去除重复项</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">a.md</span><span class="token punctuation">:</span> b.md c.md
</span><span class="code-line">  echo <span class="token variable">$^</span>
</span></code></pre>
<h4 id="-3"><a aria-hidden="true" tabindex="-1" href="#-3"><span class="icon icon-link"></span></a><code>$+</code></h4>
<p><code>$^</code> 指代所有的前置条件，不会去除重复项</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">a.md</span><span class="token punctuation">:</span> b.md c.md c.md
</span><span class="code-line">	echo <span class="token variable">$+</span>
</span></code></pre>
<h4 id="-4"><a aria-hidden="true" tabindex="-1" href="#-4"><span class="icon icon-link"></span></a><code>$?</code></h4>
<p><code>$?</code> 指代更新的依赖，只有最近更新过的依赖才会引用</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">a.md</span><span class="token punctuation">:</span> b.md c.md c.md
</span><span class="code-line">	cat <span class="token variable">$?</span> > a.md
</span></code></pre>
<h4 id="-5"><a aria-hidden="true" tabindex="-1" href="#-5"><span class="icon icon-link"></span></a><code>$*</code></h4>
<p><code>$*</code> 指代匹配符匹配的部分</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">main.o</span><span class="token punctuation">:</span> main.c
</span><span class="code-line">	clang -o <span class="token variable">$*</span> <span class="token variable">$*.c</span>
</span></code></pre>
<hr>
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> main
</span><span class="code-line"><span class="token comment"># 此时 cc  main.c -o main</span>
</span></code></pre>
<h4 id="-6"><a aria-hidden="true" tabindex="-1" href="#-6"><span class="icon icon-link"></span></a><code>$%</code></h4>
<p><code>$%</code>: 仅当目标是函数库文件中，表示规则中的目标成员名</p>
<ul class="style-round">
<li>windows 中是 <code>.lib</code> 文件</li>
<li>unix 中是 <code>.a</code> 文件</li>
</ul>
<!--rehype:className=style-round-->
</div></div></div><div class="wrap h3body-not-exist col-span-2"><div class="wrap-header h3wrap"><h3 id="内置命名变量的参数"><a aria-hidden="true" tabindex="-1" href="#内置命名变量的参数"><span class="icon icon-link"></span></a>内置命名变量的参数</h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-2-->
<p>这些变量都是相关下面的命令的参数。如果没有指明其默认值，那么其默认值都是空。</p>





























































<table class="left-align"><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>ARFLAGS</code></td><td align="left">函数库打包程序AR命令的参数。默认值是 <code>rv</code></td></tr><tr><td align="left"><code>ASFLAGS</code></td><td align="left">汇编语言编译器参数。（当明显地调用 <code>.s</code> 或 <code>.S</code> 文件时）</td></tr><tr><td align="left"><code>CFLAGS</code></td><td align="left">C 语言编译器参数。</td></tr><tr><td align="left"><code>CXXFLAGS</code></td><td align="left">C++ 语言编译器参数。</td></tr><tr><td align="left"><code>COFLAGS</code></td><td align="left">RCS 命令参数。</td></tr><tr><td align="left"><code>CPPFLAGS</code></td><td align="left">C 预处理器参数。（ <code>C</code> 和 <code>Fortran</code> 编译器也会用到）。</td></tr><tr><td align="left"><code>FFLAGS</code></td><td align="left">Fortran 语言编译器参数。</td></tr><tr><td align="left"><code>GFLAGS</code></td><td align="left">SCCS <code>get</code> 程序参数。</td></tr><tr><td align="left"><code>LDFLAGS</code></td><td align="left">链接器参数。（如：<code>ld</code> ）</td></tr><tr><td align="left"><code>PFLAGS</code></td><td align="left">Pascal 语言编译器参数。</td></tr><tr><td align="left"><code>LFLAGS</code></td><td align="left">Lex 文法分析器参数。</td></tr><tr><td align="left"><code>RFLAGS</code></td><td align="left">Ratfor 程序的 Fortran 编译器参数。</td></tr><tr><td align="left"><code>YFLAGS</code></td><td align="left">Yacc 文法分析器参数。</td></tr></tbody></table>
<!--rehype:className=left-align-->
</div></div></div><div class="wrap h3body-exist col-span-2"><div class="wrap-header h3wrap"><h3 id="内置已命名的变量"><a aria-hidden="true" tabindex="-1" href="#内置已命名的变量"><span class="icon icon-link"></span></a>内置已命名的变量</h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-2-->

























































































<table class="left-align"><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>AR</code></td><td align="left">函数库打包程序。默认命令是 <code>ar</code></td></tr><tr><td align="left"><code>AS</code></td><td align="left">汇编语言编译程序。默认命令是 <code>as</code></td></tr><tr><td align="left"><code>CC</code></td><td align="left">C 语言编译程序。默认命令是 <code>cc</code></td></tr><tr><td align="left"><code>CXX</code></td><td align="left">C++ 语言编译程序。默认命令是 <code>g++</code></td></tr><tr><td align="left"><code>CO</code></td><td align="left">从 RCS 文件中扩展文件程序。默认命令是 <code>co</code></td></tr><tr><td align="left"><code>CPP</code></td><td align="left">C 程序的预处理器（输出是标准输出设备）。默认命令是 <code>$(CC) –E</code></td></tr><tr><td align="left"><code>FC</code></td><td align="left">Fortran 和 Ratfor 的编译器和预处理程序。默认命令是 <code>f77</code></td></tr><tr><td align="left"><code>GET</code></td><td align="left">从 SCCS 文件中扩展文件的程序。默认命令是 <code>get</code></td></tr><tr><td align="left"><code>LEX</code></td><td align="left">Lex 方法分析器程序（针对于 C 或 Ratfor）。默认命令是 <code>lex</code></td></tr><tr><td align="left"><code>PC</code></td><td align="left">Pascal 语言编译程序。默认命令是 <code>pc</code></td></tr><tr><td align="left"><code>YACC</code></td><td align="left">Yacc 文法分析器（针对于 C 程序）。默认命令是 <code>yacc</code></td></tr><tr><td align="left"><code>YACCR</code></td><td align="left">Yacc 文法分析器（针对于 Ratfor 程序）。默认命令是 <code>yacc –r</code></td></tr><tr><td align="left"><code>MAKEINFO</code></td><td align="left">转换 Texinfo 源文件（.texi）到 Info 文件程序。默认命令是 <code>makeinfo</code></td></tr><tr><td align="left"><code>TEX</code></td><td align="left">从 TeX 源文件创建TeX DVI文件的程序。默认命令是 <code>tex</code></td></tr><tr><td align="left"><code>TEXI2DVI</code></td><td align="left">从 Texinfo 源文件创建 TeX DVI 文件的程序。默认命令是 <code>texi2dvi</code></td></tr><tr><td align="left"><code>WEAVE</code></td><td align="left">转换 Web 到 TeX 的程序。默认命令是 <code>weave</code></td></tr><tr><td align="left"><code>CWEAVE</code></td><td align="left">转换 C Web 到 TeX 的程序。默认命令是 <code>cweave</code></td></tr><tr><td align="left"><code>TANGLE</code></td><td align="left">转换 Web 到 Pascal 语言的程序。默认命令是 <code>tangle</code></td></tr><tr><td align="left"><code>CTANGLE</code></td><td align="left">转换 C Web 到 C。默认命令是 <code>ctangle</code></td></tr><tr><td align="left"><code>RM</code></td><td align="left">删除文件命令。默认命令是 <code>rm –f</code></td></tr></tbody></table>
<!--rehype:className=left-align-->
<h4 id="内置的变量"><a aria-hidden="true" tabindex="-1" href="#内置的变量"><span class="icon icon-link"></span></a>内置的变量</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">{</span>CC<span class="token punctuation">}</span> -o main main.c
</span></code></pre>
</div></div></div></div></div><div class="wrap h2body-exist"><div class="wrap-header h2wrap"><h2 id="书写规则"><a aria-hidden="true" tabindex="-1" href="#书写规则"><span class="icon icon-link"></span></a>书写规则</h2><div class="wrap-body">
</div></div><div class="h2wrap-body"><div class="wrap h3body-exist col-span-3"><div class="wrap-header h3wrap"><h3 id="文件搜寻vpath"><a aria-hidden="true" tabindex="-1" href="#文件搜寻vpath"><span class="icon icon-link"></span></a>文件搜寻（<code>vpath</code>）</h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-3-->
<p>如果没有指定 vpath 变量，make 只会在当前的目录中去寻找依赖文件和目标文件。否则，如果当前目录没有，就会到指定的目录中去寻找</p>





















<table><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>vpath &#x3C;pattern> &#x3C;directories></code></td><td align="left">为符合模式 &#x3C;pattern> 的文件指定搜索目录 &#x3C;directories></td></tr><tr><td align="left"><code>vpath &#x3C;pattern></code></td><td align="left">清除符合模式 &#x3C;pattern> 的文件的搜索目录。</td></tr><tr><td align="left"><code>vpath</code></td><td align="left">清除所有已被设置好了的文件搜索目录</td></tr></tbody></table>
<h4 id="-7"><a aria-hidden="true" tabindex="-1" href="#-7"><span class="icon icon-link"></span></a><code>%</code></h4>
<ul>
<li>vpath 使用方法中的 &#x3C;pattern> 需要包含 <code>%</code> 字符。<code>%</code> 的意思是匹配零或若干字符（类似于<strong>通配符</strong>）,并且引用规则是需要使用<strong>自动变量</strong></li>
</ul>
<pre class="auto-wrap"><code class="language-makefile code-highlight"><span class="code-line"><span class="token keyword">vpath</span> %.c dist
</span><span class="code-line">TARGET <span class="token operator">=</span> hello
</span><span class="code-line">OBJ <span class="token operator">=</span> bar.o foo.o
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol"><span class="token variable">$</span>(TARGET)</span><span class="token punctuation">:</span> <span class="token variable">$</span><span class="token punctuation">(</span>OBJ<span class="token punctuation">)</span>
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -o <span class="token variable">$@</span> <span class="token variable">$^</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol">%.o</span><span class="token punctuation">:</span> <span class="token variable">$.c</span>
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -o <span class="token variable">$&#x3C;</span> -o <span class="token comment">#@</span>
</span></code></pre>
<!--rehype:className=auto-wrap-->
</div></div></div><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="通配符"><a aria-hidden="true" tabindex="-1" href="#通配符"><span class="icon icon-link"></span></a>通配符</h3><div class="wrap-body">
<h4 id="-8"><a aria-hidden="true" tabindex="-1" href="#-8"><span class="icon icon-link"></span></a><code>*</code></h4>
<p><code>*</code>：与 linux 系统下的一样</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># 清除所有 .o 结尾的文件</span>
</span><span class="code-line"><span class="token target symbol">clean</span><span class="token punctuation">:</span>
</span><span class="code-line">    rm -f *.o
</span></code></pre>
<h4 id="-9"><a aria-hidden="true" tabindex="-1" href="#-9"><span class="icon icon-link"></span></a><code>~</code></h4>
<p><code>~</code>：在 linux 或 mac 下表示用户目录，win 下表示 <code>HOME</code> 环境变量</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">    ls ~
</span></code></pre>
<h4 id="-10"><a aria-hidden="true" tabindex="-1" href="#-10"><span class="icon icon-link"></span></a><code>?</code></h4>
<p><code>?</code>: 与在 linux 等类似，可以匹配单个字符</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	ls -ll packag?.json
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="静态模式"><a aria-hidden="true" tabindex="-1" href="#静态模式"><span class="icon icon-link"></span></a>静态模式</h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">TARGET</span><span class="token punctuation">:</span> PREREQUISITES <span class="token punctuation">:</span>PREREQUISITES
</span><span class="code-line">  COMMAMD
</span><span class="code-line"><span class="token comment">#...</span>
</span></code></pre>
<ul>
<li><code>target</code> 定义了一系列的目标文件</li>
<li>第一个 <code>prerequisites</code> 是指明了 target 的模式，也就是的目标集模式。</li>
<li>第二个 <code>prerequisites</code> 是目标的依赖模式，它对第一个 <code>prerequisites</code> 形成的模式再进行一次依赖目标的定义</li>
</ul>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">objects <span class="token operator">=</span> foo.o main.o
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol"><span class="token variable">$</span>(objects)</span><span class="token punctuation">:</span> %.o<span class="token punctuation">:</span> %.c
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -c <span class="token variable">$</span><span class="token punctuation">(</span>CFLAGS<span class="token punctuation">)</span> <span class="token variable">$&#x3C;</span> -o <span class="token variable">$@</span>
</span></code></pre>
<hr>
<p>相当于:</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">foo.o</span> <span class="token punctuation">:</span> foo.c
</span><span class="code-line">    <span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -c <span class="token variable">$</span><span class="token punctuation">(</span>CFLAGS<span class="token punctuation">)</span> foo.c -o foo.o
</span><span class="code-line"><span class="token target symbol">main.o</span> <span class="token punctuation">:</span> main.c
</span><span class="code-line">    <span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -c <span class="token variable">$</span><span class="token punctuation">(</span>CFLAGS<span class="token punctuation">)</span> main.c -o main.o
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="伪目标"><a aria-hidden="true" tabindex="-1" href="#伪目标"><span class="icon icon-link"></span></a>伪目标</h3><div class="wrap-body">
<ul>
<li><strong>伪目标</strong>并不是一个文件，只是一个标签。只有通过显式地指明这个<strong>目标</strong>才能让其生效</li>
<li>使用 <code>.PHONY</code> 来显式地指明目标是 <code>伪目标</code></li>
</ul>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token builtin-target builtin">.PHONY</span> <span class="token punctuation">:</span> clean
</span><span class="code-line"><span class="token target symbol">clean</span> <span class="token punctuation">:</span>
</span><span class="code-line">    rm *.o temp
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist col-span-2"><div class="wrap-header h3wrap"><h3 id="约定俗成的规则"><a aria-hidden="true" tabindex="-1" href="#约定俗成的规则"><span class="icon icon-link"></span></a>约定俗成的规则</h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-2-->









































<table class="style-round"><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>all</code></td><td align="left">该伪目标是所有目标的目标，一般用于编译所有的目标</td></tr><tr><td align="left"><code>clean</code></td><td align="left">该伪目标用于删除所有由 make 创建的文件</td></tr><tr><td align="left"><code>install</code></td><td align="left">该伪目标用于安装已编译好的程序，即将目标执行文件拷贝到指定目标中</td></tr><tr><td align="left"><code>print</code></td><td align="left">该伪目标用于例出改变过的源文件</td></tr><tr><td align="left"><code>tar</code></td><td align="left">该伪目标用于把源程序打包备份为 tar 文件</td></tr><tr><td align="left"><code>dist</code></td><td align="left">该伪目标用于创建压缩文件，一般将 tar 文件压成 Z 或 gz 文件</td></tr><tr><td align="left"><code>TAGS</code></td><td align="left">该伪目标用于更新所有的目标，以备完整地重编译使用</td></tr><tr><td align="left"><code>check/test</code></td><td align="left">这两个伪目标用于测试 makefile 的流程</td></tr></tbody></table>
<!--rehype:className=style-round-->
<!--rehype:className=auto-wrap-->
</div></div></div></div></div><div class="wrap h2body-exist"><div class="wrap-header h2wrap"><h2 id="命令"><a aria-hidden="true" tabindex="-1" href="#命令"><span class="icon icon-link"></span></a>命令</h2><div class="wrap-body">
</div></div><div class="h2wrap-body"><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="回声"><a aria-hidden="true" tabindex="-1" href="#回声"><span class="icon icon-link"></span></a>回声（<code>@</code>）</h3><div class="wrap-body">
<p>正常情况下，make会打印每条命令，然后再执行，这就叫做回声（echoing）</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">all</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token comment"># 会有命令执行显示</span>
</span><span class="code-line">	echo Hello, world
</span></code></pre>
<hr>
<pre class="auto-wrap"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">all</span><span class="token punctuation">:</span>
</span><span class="code-line">  <span class="token comment"># 不会有命令执行的显示</span>
</span><span class="code-line">	<span class="token operator">@</span>echo Hello, world
</span></code></pre>
<!--rehype:className=auto-wrap-->
</div></div></div><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="显示命令禁止命令"><a aria-hidden="true" tabindex="-1" href="#显示命令禁止命令"><span class="icon icon-link"></span></a>显示命令、禁止命令</h3><div class="wrap-body">
<h4 id="显示命令"><a aria-hidden="true" tabindex="-1" href="#显示命令"><span class="icon icon-link"></span></a>显示命令</h4>
<p>如果我们只希望显示命令，而不希望执行命令，可以使用 <code>-n</code> 或者 <code>--just-print</code></p>
<pre class="language-bash"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> all --just-print 
</span><span class="code-line">$ <span class="token function">make</span> all <span class="token parameter variable">-n</span> 
</span></code></pre>
<h4 id="禁止命令"><a aria-hidden="true" tabindex="-1" href="#禁止命令"><span class="icon icon-link"></span></a>禁止命令</h4>
<p><code>-s</code> 或 <code>--silent</code> 或 <code>--quiet</code> 与 <code>@</code> 一样，用于禁止回声</p>
<pre class="auto-wrap"><code class="language-bash code-highlight"><span class="code-line">$ <span class="token function">make</span> all <span class="token parameter variable">-s</span> 
</span></code></pre>
<!--rehype:className=auto-wrap-->
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="执行命令"><a aria-hidden="true" tabindex="-1" href="#执行命令"><span class="icon icon-link"></span></a>执行命令</h3><div class="wrap-body">
<p>使用 tab 及换行</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">exec</span><span class="token punctuation">:</span>
</span><span class="code-line">    cd /home/hchen
</span><span class="code-line">    pwd
</span></code></pre>
<hr>
<p>使用 <code>;</code></p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">exec</span><span class="token punctuation">:</span>
</span><span class="code-line">    cd /home/hchen<span class="token punctuation">;</span> pwd
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist col-span-3"><div class="wrap-header h3wrap"><h3 id="make-参数"><a aria-hidden="true" tabindex="-1" href="#make-参数"><span class="icon icon-link"></span></a>make 参数</h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-3-->









































































































<table class="left-align"><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>-b</code>,<code>-m</code></td><td align="left">忽略和其它版本make的兼容性</td></tr><tr><td align="left"><code>-B</code></td><td align="left">(<code>--always-make</code>) 认为所有的目标都需要重编译</td></tr><tr><td align="left"><code>-C &#x3C;dir></code></td><td align="left">(<code>--directory=&#x3C;dir></code>) 指定读取makefile的目录</td></tr><tr><td align="left"><code>-e</code></td><td align="left">(<code>--environment-overrides</code>) 指明环境变量的值覆盖 makefile 中定义的变量的值</td></tr><tr><td align="left"><code>-f=&#x3C;file></code></td><td align="left">指定需要执行的makefile</td></tr><tr><td align="left"><code>-h</code></td><td align="left">显示帮助信息</td></tr><tr><td align="left"><code>-i</code></td><td align="left">(<code>--ignore-errors</code>)在执行时忽略所有的错误</td></tr><tr><td align="left"><code>-I &#x3C;dir></code></td><td align="left">(<code>--include-dir=&#x3C;dir></code>) 指定一个被包含 makefile 的搜索目标</td></tr><tr><td align="left"><code>-j [&#x3C;nums>]</code></td><td align="left">(<code>--jobs[=&#x3C;jobsnum>]</code>)指同时运行命令的个数</td></tr><tr><td align="left"><code>-k</code></td><td align="left">(<code>--keep-going</code>)出错也不停止运行</td></tr><tr><td align="left"><code>-l &#x3C;load></code></td><td align="left"><code>--load-average[=&#x3C;load>]</code>、<code>-max-load[=&#x3C;load>]</code> 指定make运行命令的负载</td></tr><tr><td align="left"><code>-n</code></td><td align="left">(<code>--just-print</code>, <code>--dry-run</code>, <code>--recon</code>) 仅输出执行过程中的命令序列，但不执行</td></tr><tr><td align="left"><code>-o &#x3C;file></code></td><td align="left">(<code>--old-file=&#x3C;file></code>, <code>--assume-old=&#x3C;file></code>)不重新生成的指定的 &#x3C;file>，即使目标的依赖文件新于它</td></tr><tr><td align="left"><code>-p</code></td><td align="left">(<code>--print-data-base</code>) 输出 makefile 中的所有数据，包括所有的规则和变量</td></tr><tr><td align="left"><code>-q</code></td><td align="left">(<code>--question</code>) 不运行命令，也不输出。仅仅是检查所指定的目标是否需要更新</td></tr><tr><td align="left"><code>-r</code></td><td align="left">(<code>--no-builtin-rules</code>) 禁止 make 使用任何隐含规则</td></tr><tr><td align="left"><code>-R</code></td><td align="left">(<code>--no-builtin-variabes</code>) 禁止 make 使用任何作用于变量上的隐含规则</td></tr><tr><td align="left"><code>-s</code></td><td align="left">(<code>--silent</code>,<code>--quiet</code>) 在命令运行时不输出命令的输出</td></tr><tr><td align="left"><code>-S</code></td><td align="left">(<code>--no-keep-going</code>, <code>--stop</code>) 取消“-k”选项的作用</td></tr><tr><td align="left"><code>-t</code></td><td align="left"><code>--touch</code> 相当于 UNIX 的 touch 命令，只是把目标的修改日期变成最新的，也就是阻止生成目标的命令运行</td></tr><tr><td align="left"><code>-v</code></td><td align="left">(<code>--version</code>) 输出 make 程序的版本、版权等关于 make 的信息</td></tr><tr><td align="left"><code>-w</code></td><td align="left">(<code>--print-directory</code>) 输出运行 makefile 之前和之后的信息。<code>--no-print-directory</code> 可以禁止 <code>-w</code></td></tr><tr><td align="left"><code>-W &#x3C;file></code></td><td align="left"><code>--what-if=&#x3C;file></code>, <code>--new-file=&#x3C;file></code>, <code>--assume-file=&#x3C;file></code> 假定目标 &#x3C;file> 需要更新，如果和 <code>-n</code> 选项使用，那么这个参数会输出该目标更新时的运行动作</td></tr><tr><td align="left"><code>--warn-undefined-variables</code></td><td align="left">只要 make 发现有未定义的变量，那么就输出警告信息</td></tr></tbody></table>
<!--rehype:className=left-align-->
</div></div></div><div class="wrap h3body-not-exist col-span-2"><div class="wrap-header h3wrap"><h3 id="-debugoptions"><a aria-hidden="true" tabindex="-1" href="#-debugoptions"><span class="icon icon-link"></span></a><code>-debug[=&#x3C;options>]</code></h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-2-->
<p>输出 make 的调试信息。下面是 &#x3C;options>的取值：</p>

































<table class="left-align"><thead><tr><th align="left">options</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>a</code></td><td align="left"><code>all</code>，输出所有的调试信息</td></tr><tr><td align="left"><code>b</code></td><td align="left"><code>basic</code>，只输出简单的调试信息。即输出不需要重编译的目标</td></tr><tr><td align="left"><code>v</code></td><td align="left"><code>verbose</code>，包括 b 的信息。输出包括 makefile 被解析的信息，不需要被重编译的依赖文件等</td></tr><tr><td align="left"><code>i</code></td><td align="left"><code>implicit</code>，输出所有的隐含规则</td></tr><tr><td align="left"><code>j</code></td><td align="left"><code>jobs</code>，输出执行规则中命令的详细信息，如命令的 PID、返回码等</td></tr><tr><td align="left"><code>m</code></td><td align="left"><code>makefile</code>，输出 make 读取 makefile，更新 makefile，执行 makefile 的信息</td></tr></tbody></table>
<!--rehype:className=left-align-->
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="make-的退出码"><a aria-hidden="true" tabindex="-1" href="#make-的退出码"><span class="icon icon-link"></span></a>make 的退出码</h3><div class="wrap-body">





















<table><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>0</code></td><td align="left">成功执行</td></tr><tr><td align="left"><code>1</code></td><td align="left">运行时出现错误</td></tr><tr><td align="left"><code>2</code></td><td align="left">使用了 <code>-q</code> 选项，并且一些目标不需要更新</td></tr></tbody></table>
</div></div></div></div></div><div class="wrap h2body-exist"><div class="wrap-header h2wrap"><h2 id="判断和循环"><a aria-hidden="true" tabindex="-1" href="#判断和循环"><span class="icon icon-link"></span></a>判断和循环</h2><div class="wrap-body">
</div></div><div class="h2wrap-body"><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="单分支条件判断"><a aria-hidden="true" tabindex="-1" href="#单分支条件判断"><span class="icon icon-link"></span></a>单分支条件判断</h3><div class="wrap-body">
<ul class="style-round">
<li><code>ifeq</code> 的意思表示条件语句的开始，表达式包含两个参数，如果相同则为真。</li>
<li><code>ifneq</code> 的意思表示条件语句的开始，表达式包含两个参数，如果不同则为真。</li>
<li><code>else</code> 表示条件表达式为假的情况。</li>
<li><code>endif</code> 表示一个条件语句的结束，任何一个条件表达式都应该以 <code>endif</code> 结束。</li>
</ul>
<!--rehype:className=style-round-->
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line"><span class="token keyword">ifeq</span> <span class="token punctuation">(</span><span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span>, cc<span class="token punctuation">)</span>
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -o foo foo.c
</span><span class="code-line"><span class="token keyword">else</span>
</span><span class="code-line">	<span class="token variable">$</span><span class="token punctuation">(</span>CC<span class="token punctuation">)</span> -o bar bar.c
</span><span class="code-line"><span class="token keyword">endif</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-exist"><div class="wrap-header h3wrap"><h3 id="多分支条件判断"><a aria-hidden="true" tabindex="-1" href="#多分支条件判断"><span class="icon icon-link"></span></a>多分支条件判断</h3><div class="wrap-body">
<h4 id="ifneq-语法"><a aria-hidden="true" tabindex="-1" href="#ifneq-语法"><span class="icon icon-link"></span></a>ifneq 语法</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token keyword">ifneq</span> <span class="token punctuation">(</span>&#x3C;arg1>, &#x3C;arg2><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token keyword">ifneq</span> <span class="token string">'&#x3C;arg1>'</span> <span class="token string">'&#x3C;arg2>'</span>
</span><span class="code-line"><span class="token keyword">ifneq</span> <span class="token string">"&#x3C;arg1>"</span> <span class="token string">"&#x3C;arg2>"</span>
</span><span class="code-line"><span class="token keyword">ifneq</span> <span class="token string">"&#x3C;arg1>"</span> <span class="token string">'&#x3C;arg2>'</span>
</span><span class="code-line"><span class="token keyword">ifneq</span> <span class="token string">'&#x3C;arg1>'</span> <span class="token string">"&#x3C;arg2>"</span>
</span></code></pre>
<h4 id="ifeq-语法"><a aria-hidden="true" tabindex="-1" href="#ifeq-语法"><span class="icon icon-link"></span></a>ifeq 语法</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token keyword">ifeq</span> <span class="token punctuation">(</span>&#x3C;arg1>, &#x3C;arg2><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token keyword">ifeq</span> <span class="token string">'&#x3C;arg1>'</span> <span class="token string">'&#x3C;arg2>'</span>
</span><span class="code-line"><span class="token keyword">ifeq</span> <span class="token string">"&#x3C;arg1>"</span> <span class="token string">"&#x3C;arg2>"</span>
</span><span class="code-line"><span class="token keyword">ifeq</span> <span class="token string">"&#x3C;arg1>"</span> <span class="token string">'&#x3C;arg2>'</span>
</span><span class="code-line"><span class="token keyword">ifeq</span> <span class="token string">'&#x3C;arg1>'</span> <span class="token string">"&#x3C;arg2>"</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="ifdef"><a aria-hidden="true" tabindex="-1" href="#ifdef"><span class="icon icon-link"></span></a>ifdef</h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token keyword">ifdef</span> &#x3C;variable-name>
</span></code></pre>
<p><code>ifdef</code> 会根据 variable-name 判断，如果为空则为真</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">bar <span class="token operator">=</span>
</span><span class="code-line">foo <span class="token operator">=</span> <span class="token variable">$</span><span class="token punctuation">(</span>bar<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token keyword">ifdef</span> foo
</span><span class="code-line">    frobozz <span class="token operator">=</span> yes
</span><span class="code-line"><span class="token keyword">else</span>
</span><span class="code-line">    frobozz <span class="token operator">=</span> no
</span><span class="code-line"><span class="token keyword">endif</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	echo <span class="token variable">$</span><span class="token punctuation">(</span>frobozz<span class="token punctuation">)</span>
</span></code></pre>
<p><code>ifndef</code> 则和 <code>ifdef</code> 是相反的意思</p>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="for-循环"><a aria-hidden="true" tabindex="-1" href="#for-循环"><span class="icon icon-link"></span></a>for 循环</h3><div class="wrap-body">
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">LIST <span class="token operator">=</span> one two three
</span><span class="code-line"><span class="token target symbol">all</span><span class="token punctuation">:</span>
</span><span class="code-line">	for i in <span class="token variable">$</span><span class="token punctuation">(</span>LIST<span class="token punctuation">)</span><span class="token punctuation">;</span> do \
</span><span class="code-line">	    echo <span class="token variable">$$i;</span> \
</span><span class="code-line">	done
</span></code></pre>
</div></div></div></div></div><div class="wrap h2body-exist"><div class="wrap-header h2wrap"><h2 id="函数"><a aria-hidden="true" tabindex="-1" href="#函数"><span class="icon icon-link"></span></a>函数</h2><div class="wrap-body">
</div></div><div class="h2wrap-body"><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---替换函数subst"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---替换函数subst"><span class="icon icon-link"></span></a>字符串处理函数 - 替换函数(<code>subst</code>)</h3><div class="wrap-body">
<p>把字串 &#x3C;text> 中的 &#x3C;from> 字符串替换成 &#x3C;to> 。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">subst</span> &#x3C;from>,&#x3C;to>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<p>示例</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">subst</span> ee,EE,feet on the street<span class="token punctuation">)</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---模式字符串替换函数patsubst"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---模式字符串替换函数patsubst"><span class="icon icon-link"></span></a>字符串处理函数 - 模式字符串替换函数(<code>patsubst</code>)</h3><div class="wrap-body">
<p>查找 &#x3C;text> 中的单词（<strong>单词以空格、Tab或回车换行分隔</strong>）是否符合模式 &#x3C;pattern>。匹配，则以 &#x3C;replacement> 替换。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">patsubst</span> &#x3C;pattern>,&#x3C;replacement>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<ul>
<li>示例</li>
</ul>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">patsubst</span> %.c,%.o,x.c.c bar.c<span class="token punctuation">)</span>
</span></code></pre>
<p>把字串 x.c.c bar.c 符合模式 %.c 的单词替换成 %.o ，返回结果是 x.c.o bar.o</p>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---去空格函数strip"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---去空格函数strip"><span class="icon icon-link"></span></a>字符串处理函数 - 去空格函数(<code>strip</code>)</h3><div class="wrap-body">
<p>去掉 <string> 字串中开头和结尾的空字符。</string></p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">strip</span> &#x3C;string><span class="token punctuation">)</span>
</span></code></pre>
<p>示例</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">strip</span> a b c <span class="token punctuation">)</span>
</span></code></pre>
<p>把字串 <code>a b c</code> 去掉开头和结尾的空格，结果是 a b c。</p>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---查找字符串函数findstring"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---查找字符串函数findstring"><span class="icon icon-link"></span></a>字符串处理函数 - 查找字符串函数(<code>findstring</code>)</h3><div class="wrap-body">
<p>在字串 &#x3C;in> 中查找 &#x3C;find> 字串。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">findstring</span> &#x3C;find>,&#x3C;in><span class="token punctuation">)</span>
</span></code></pre>
<p>示例：</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">findstring</span> a,a b c<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">findstring</span> a,b c<span class="token punctuation">)</span>
</span></code></pre>
<p>第一个函数返回 a 字符串，第二个返回空字符串</p>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---过滤函数filter"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---过滤函数filter"><span class="icon icon-link"></span></a>字符串处理函数 - 过滤函数(<code>filter</code>)</h3><div class="wrap-body">
<p>以 &#x3C;pattern> 模式过滤 &#x3C;text> 字符串中的单词，保留符合模式 &#x3C;pattern> 的单词。可以有多个模式。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">filter</span> &#x3C;pattern...>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<p>示例</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">sources <span class="token operator">:=</span> foo.c bar.c baz.s ugh.h
</span><span class="code-line"><span class="token target symbol">foo</span><span class="token punctuation">:</span> <span class="token variable">$</span><span class="token punctuation">(</span>sources<span class="token punctuation">)</span>
</span><span class="code-line">    cc <span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">filter</span> %.c %.s,<span class="token variable">$</span><span class="token punctuation">(</span>sources<span class="token punctuation">)</span><span class="token punctuation">)</span> -o foo
</span><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">filter</span> %.c %.s,<span class="token variable">$</span><span class="token punctuation">(</span>sources<span class="token punctuation">)</span><span class="token punctuation">)</span> 
</span><span class="code-line"><span class="token comment"># 返回的值是 foo.c bar.c baz.s</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---反过滤函数filter-out"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---反过滤函数filter-out"><span class="icon icon-link"></span></a>字符串处理函数 - 反过滤函数(<code>filter-out</code>)</h3><div class="wrap-body">
<p>以 &#x3C;pattern> 模式过滤 &#x3C;text> 字符串中的单词，去除符合模式 &#x3C;pattern> 的单词。可以有多个模式。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">filter-out</span> &#x3C;pattern...>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<p>示例：</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">objects<span class="token operator">=</span>main1.o foo.o main2.o bar.o
</span><span class="code-line">mains<span class="token operator">=</span>main1.o main2.o
</span><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">filter-out</span> <span class="token variable">$</span><span class="token punctuation">(</span>mains<span class="token punctuation">)</span>,<span class="token variable">$</span><span class="token punctuation">(</span>objects<span class="token punctuation">)</span><span class="token punctuation">)</span> 
</span><span class="code-line"><span class="token comment"># 返回值是 foo.o bar.o 。</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---排序函数sort"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---排序函数sort"><span class="icon icon-link"></span></a>字符串处理函数 - 排序函数(<code>sort</code>)</h3><div class="wrap-body">
<p>给字符串 &#x3C;list> 中的单词排序（升序）。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">sort</span> &#x3C;list><span class="token punctuation">)</span>
</span></code></pre>
<ul>
<li>示例：<code>$(sort foo bar lose)</code> 返回 <code>bar foo lose</code></li>
<li>注意：sort 函数会去掉 <code>&#x3C;list></code> 中相同的单词</li>
</ul>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---取单词函数word"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---取单词函数word"><span class="icon icon-link"></span></a>字符串处理函数 - 取单词函数（<code>word</code>)</h3><div class="wrap-body">
<p>取字符串 &#x3C;text> 中第 &#x3C;n> 个单词。（从一开始）</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">word</span> &#x3C;n>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<p>示例：<code>$(word 2, foo bar baz)</code> 返回值是 <code>bar</code></p>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---取单词串函数wordlist"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---取单词串函数wordlist"><span class="icon icon-link"></span></a>字符串处理函数 - 取单词串函数(<code>wordlist</code>)</h3><div class="wrap-body">
<ul>
<li>从字符串 &#x3C;text> 中取从 &#x3C;s> 开始到 &#x3C;e> 的单词串。&#x3C;s> 和 &#x3C;e> 是一个数字。</li>
</ul>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">wordlist</span> &#x3C;ss>,&#x3C;e>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<p>示例：<code>$(wordlist 2, 3, foo bar baz)</code> 返回值是 bar baz。</p>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---单词个数统计函数words"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---单词个数统计函数words"><span class="icon icon-link"></span></a>字符串处理函数 - 单词个数统计函数(<code>words</code>)</h3><div class="wrap-body">
<ul>
<li>统计 &#x3C;text> 中字符串中的单词个数。</li>
</ul>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">words</span> &#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<ul>
<li>示例：<code>$(words, foo bar baz)</code> 返回值是 3。</li>
</ul>
</div></div></div><div class="wrap h3body-not-exist"><div class="wrap-header h3wrap"><h3 id="字符串处理函数---首单词函数firstword"><a aria-hidden="true" tabindex="-1" href="#字符串处理函数---首单词函数firstword"><span class="icon icon-link"></span></a>字符串处理函数 - 首单词函数(<code>firstword</code>)</h3><div class="wrap-body">
<ul>
<li>取字符串 &#x3C;text> 中的第一个单词。</li>
</ul>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">firstword</span> &#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<ul>
<li>示例：<code>$(firstword foo bar)</code> 返回值是 <code>foo</code></li>
</ul>
</div></div></div><div class="wrap h3body-exist row-span-2"><div class="wrap-header h3wrap"><h3 id="文件名操作函数"><a aria-hidden="true" tabindex="-1" href="#文件名操作函数"><span class="icon icon-link"></span></a>文件名操作函数</h3><div class="wrap-body">
<!--rehype:wrap-class=row-span-2-->
<h4 id="取目录函数dir"><a aria-hidden="true" tabindex="-1" href="#取目录函数dir"><span class="icon icon-link"></span></a>取目录函数(<code>dir</code>)</h4>
<p>从文件名序列 &#x3C;names> 中取出目录部分。目录部分是指最后一个反斜杠（<code>/</code>）之前的部分。如果没有反斜杠，那么返回 <code>./</code>。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">dir</span> &#x3C;names...><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">dir</span> src/foo.c hacks<span class="token punctuation">)</span> 
</span><span class="code-line"><span class="token comment">#返回值是 src/ ./</span>
</span></code></pre>
<h4 id="取文件函数notdir"><a aria-hidden="true" tabindex="-1" href="#取文件函数notdir"><span class="icon icon-link"></span></a>取文件函数(<code>notdir</code>)</h4>
<p>从文件名序列 &#x3C;names> 中取出非目录部分。非目录部分是指最後一个反斜杠（<code>/</code>）之后的部分。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">notdir</span> &#x3C;names...><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">notdir</span> src/foo.c hacks<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># 返回值是 foo.c hacks</span>
</span></code></pre>
<h4 id="取后缀函数suffix"><a aria-hidden="true" tabindex="-1" href="#取后缀函数suffix"><span class="icon icon-link"></span></a>取后缀函数（<code>suffix</code>)</h4>
<p>从文件名序列 &#x3C;names> 中取出各个文件名的后缀</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">suffix</span> &#x3C;names...><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">suffix</span> src/foo.c src-1.0/bar.c hacks<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># 返回值是 .c .c</span>
</span></code></pre>
<h4 id="取前缀函数basename"><a aria-hidden="true" tabindex="-1" href="#取前缀函数basename"><span class="icon icon-link"></span></a>取前缀函数(<code>basename</code>)</h4>
<p>从文件名序列 &#x3C;names> 中取出各个文件名的前缀部分。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">basename</span> &#x3C;names...><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">basename</span> src/foo.c src-1.0/bar.c hacks<span class="token punctuation">)</span> 
</span><span class="code-line"><span class="token comment"># 返回值是 src/foo src-1.0/bar hacks</span>
</span></code></pre>
<h4 id="加后缀函数addsuffix"><a aria-hidden="true" tabindex="-1" href="#加后缀函数addsuffix"><span class="icon icon-link"></span></a>加后缀函数(<code>addsuffix</code>)</h4>
<p>把后缀 &#x3C;suffix> 加到 &#x3C;names> 中的每个单词后面</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">addsuffix</span> &#x3C;suffix>,&#x3C;names...><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">addsuffix</span> .c,foo bar<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># 返回值是 foo.c bar.c </span>
</span></code></pre>
<h4 id="加前缀函数addprefix"><a aria-hidden="true" tabindex="-1" href="#加前缀函数addprefix"><span class="icon icon-link"></span></a>加前缀函数(<code>addprefix</code>)</h4>
<p>把前缀 &#x3C;prefix> 加到 &#x3C;names> 中的每个单词前面。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span>addprefix &#x3C;prefix>,&#x3C;names...><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span>addprefix src/,foo bar<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># 返回值是 src/foo src/bar 。</span>
</span></code></pre>
<h4 id="连接函数join"><a aria-hidden="true" tabindex="-1" href="#连接函数join"><span class="icon icon-link"></span></a>连接函数(<code>join</code>)</h4>
<p>把 &#x3C;list2> 中的单词对应地加到 &#x3C;list1> 的单词后面。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">join</span> &#x3C;list1>,&#x3C;list2><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">join</span> aaa bbb , 111 222 333<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># 返回值是 aaa111 bbb222 333 。</span>
</span></code></pre>
</div></div></div><div class="wrap h3body-exist col-span-2"><div class="wrap-header h3wrap"><h3 id="其它函数"><a aria-hidden="true" tabindex="-1" href="#其它函数"><span class="icon icon-link"></span></a>其它函数</h3><div class="wrap-body">
<!--rehype:wrap-class=col-span-2-->
<h4 id="foreach-函数"><a aria-hidden="true" tabindex="-1" href="#foreach-函数"><span class="icon icon-link"></span></a>foreach 函数</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">foreach</span> &#x3C;var>,&#x3C;list>,&#x3C;text><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token comment"># $(name) 中的单词会被挨个取出，并存到变量 n 中，</span>
</span><span class="code-line"><span class="token comment"># $(n).o 每次根据 $(n) 计算出一个值，这些值以空格分隔，最后作为 foreach 函数的返回</span>
</span><span class="code-line">names <span class="token operator">:=</span> a b c d
</span><span class="code-line">files <span class="token operator">:=</span> <span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">foreach</span> n,<span class="token variable">$</span><span class="token punctuation">(</span>names<span class="token punctuation">)</span>,<span class="token variable">$</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span>.o<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	echo <span class="token variable">$</span><span class="token punctuation">(</span>files<span class="token punctuation">)</span>
</span></code></pre>
<h4 id="if-函数"><a aria-hidden="true" tabindex="-1" href="#if-函数"><span class="icon icon-link"></span></a>if 函数</h4>
<p>与之前的条件语句——<code>ifeq</code> 类似</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">if</span> &#x3C;condition>,&#x3C;then-part><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># 或者</span>
</span><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">if</span> &#x3C;condition>,&#x3C;then-part>,&#x3C;<span class="token keyword">else</span>-part><span class="token punctuation">)</span>
</span></code></pre>
<h4 id="call-函数"><a aria-hidden="true" tabindex="-1" href="#call-函数"><span class="icon icon-link"></span></a>call 函数</h4>
<p>call 函数是唯一一个可以用来创建新的参数化的函数。</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">call</span> &#x3C;expression>,&#x3C;parm1>,&#x3C;parm2>,...,&#x3C;parmn><span class="token punctuation">)</span>
</span></code></pre>
<hr>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">reverse <span class="token operator">=</span>  <span class="token variable">$</span><span class="token punctuation">(</span>2<span class="token punctuation">)</span> <span class="token variable">$</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line">foo <span class="token operator">=</span> <span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">call</span> reverse,a,b<span class="token punctuation">)</span>
</span><span class="code-line">
</span><span class="code-line"><span class="token target symbol">run</span><span class="token punctuation">:</span>
</span><span class="code-line">	echo <span class="token variable">$</span><span class="token punctuation">(</span>foo<span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># b a</span>
</span></code></pre>
<h4 id="shell-函数"><a aria-hidden="true" tabindex="-1" href="#shell-函数"><span class="icon icon-link"></span></a>shell 函数</h4>
<p>使用操作系统 Shell 的命令</p>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line">contents <span class="token operator">:=</span> <span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">shell</span> cat foo<span class="token punctuation">)</span>
</span><span class="code-line">files <span class="token operator">:=</span> <span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">shell</span> echo *.c<span class="token punctuation">)</span>
</span></code></pre>
<h4 id="控制-make-的函数"><a aria-hidden="true" tabindex="-1" href="#控制-make-的函数"><span class="icon icon-link"></span></a>控制 make 的函数</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">error</span> &#x3C;text ...><span class="token punctuation">)</span>
</span><span class="code-line"><span class="token comment"># and</span>
</span><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">warning</span> &#x3C;text ...><span class="token punctuation">)</span>
</span></code></pre>
<h4 id="origin-函数"><a aria-hidden="true" tabindex="-1" href="#origin-函数"><span class="icon icon-link"></span></a>origin 函数</h4>
<pre class="language-makefile"><code class="language-makefile code-highlight"><span class="code-line"><span class="token variable">$</span><span class="token punctuation">(</span><span class="token function">origin</span> &#x3C;variable><span class="token punctuation">)</span>
</span></code></pre>
<p>origin 函数用于告诉这个变量的从何而来</p>





































<table class="left-align"><thead><tr><th align="left">:-</th><th align="left">:-</th></tr></thead><tbody><tr><td align="left"><code>undefined</code></td><td align="left">如果 &#x3C;variable> 未定义，返回 <code>undefined</code></td></tr><tr><td align="left"><code>default</code></td><td align="left">如果 &#x3C;variable> 是默认的，如 <code>CC</code></td></tr><tr><td align="left"><code>environment</code></td><td align="left">如果 &#x3C;variable> 是环境变量，并且当 Makefile 执行时，-e 参数没有被打开</td></tr><tr><td align="left"><code>file</code></td><td align="left">如果 &#x3C;variable> 这个变量被定义在 Makefile 中。</td></tr><tr><td align="left"><code>command line</code></td><td align="left">如果 &#x3C;variable> 这个变量是被命令行定义的。</td></tr><tr><td align="left"><code>override</code></td><td align="left">如果 &#x3C;variable> 是被 override 指示符重新定义的。</td></tr><tr><td align="left"><code>automatic</code></td><td align="left">如果 &#x3C;variable> 是一个命令运行中的自动化变量</td></tr></tbody></table>
<!--rehype:className=left-align-->
</div></div></div></div></div><div class="wrap h2body-not-exist"><div class="wrap-header h2wrap"><h2 id="另见"><a aria-hidden="true" tabindex="-1" href="#另见"><span class="icon icon-link"></span></a>另见</h2><div class="wrap-body">
<ul>
<li><a href="https://seisman.github.io/how-to-write-makefile/overview.html">make 中文教程</a> <em>(seisman.github.io)</em></li>
<li><a href="https://www.gnu.org/software/make/manual/make.html#toc-Overview-of-make">make 手册</a> <em>(<a href="http://www.gnu.org">www.gnu.org</a>)</em></li>
<li><a href="https://www.gnu.org/software/make/">make 官网</a> <em><a href="http://www.gnu.org">www.gnu.org</a></em></li>
</ul>
</div></div><div class="h2wrap-body"></div></div></div><script src="https://giscus.app/client.js" data-repo="jaywcjlove/reference" data-repo-id="R_kgDOID2-Mw" data-category="Q&#x26;A" data-category-id="DIC_kwDOID2-M84CS5wo" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="bottom" data-theme="dark" data-lang="zh-CN" crossorigin="anonymous" async></script><div class="giscus"></div></div><footer class="footer-wrap"><footer class="max-container">© 2022 Kenny Wang.</footer></footer><script src="../data.js?v=1.5.2" defer></script><script src="../js/fuse.min.js?v=1.5.2" defer></script><script src="../js/main.js?v=1.5.2" defer></script><div id="mysearch"><div class="mysearch-box"><div class="mysearch-input"><div><svg xmlns="http://www.w3.org/2000/svg" height="1em" width="1em" viewBox="0 0 18 18">
  <path fill="currentColor" d="M17.71,16.29 L14.31,12.9 C15.4069846,11.5024547 16.0022094,9.77665502 16,8 C16,3.581722 12.418278,0 8,0 C3.581722,0 0,3.581722 0,8 C0,12.418278 3.581722,16 8,16 C9.77665502,16.0022094 11.5024547,15.4069846 12.9,14.31 L16.29,17.71 C16.4777666,17.8993127 16.7333625,18.0057983 17,18.0057983 C17.2666375,18.0057983 17.5222334,17.8993127 17.71,17.71 C17.8993127,17.5222334 18.0057983,17.2666375 18.0057983,17 C18.0057983,16.7333625 17.8993127,16.4777666 17.71,16.29 Z M2,8 C2,4.6862915 4.6862915,2 8,2 C11.3137085,2 14,4.6862915 14,8 C14,11.3137085 11.3137085,14 8,14 C4.6862915,14 2,11.3137085 2,8 Z"></path>
</svg><input id="mysearch-input" type="search" placeholder="搜索" autocomplete="off"><div class="mysearch-clear"></div></div><button id="mysearch-close" type="button">搜索</button></div><div class="mysearch-result"><div id="mysearch-menu"></div><div id="mysearch-content"></div></div></div></div></body>
</html>
